package com.example.furniture.service.impl;

import com.example.furniture.entity.Category;
import com.example.furniture.entity.Furniture;
import com.example.furniture.entity.User;
import com.example.furniture.mapper.CategoryMapper;
import com.example.furniture.mapper.FurnitureMapper;
import com.example.furniture.mapper.UserMapper;
import com.example.furniture.service.StatisticsService;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 统计服务实现类
 * 提供系统统计数据的业务逻辑处理
 * 
 * @author 家具商城系统
 * @version 1.0
 * @since 2024-01-01
 */
@Service
public class StatisticsServiceImpl implements StatisticsService {

    private static final Logger logger = LoggerFactory.getLogger(StatisticsServiceImpl.class);
    private final UserMapper userMapper;
    private final FurnitureMapper furnitureMapper;
    private final CategoryMapper categoryMapper;

    /**
     * 构造函数，注入数据访问层
     * 
     * @param userMapper 用户数据访问层
     * @param furnitureMapper 家具数据访问层
     * @param categoryMapper 分类数据访问层
     */
    public StatisticsServiceImpl(UserMapper userMapper, 
                                FurnitureMapper furnitureMapper, 
                                CategoryMapper categoryMapper) {
        this.userMapper = userMapper;
        this.furnitureMapper = furnitureMapper;
        this.categoryMapper = categoryMapper;
    }

    /**
     * 获取系统统计概览
     * 
     * @return 统计概览数据
     */
    @Override
    public Map<String, Object> getOverview() {
        logger.debug("获取系统统计概览");
        
        try {
            // 获取基础数据
            List<User> users = userMapper.selectAll();
            List<Furniture> furniture = furnitureMapper.selectAll();
            List<Category> categories = categoryMapper.selectAll();
            
            // 计算统计数据
            int userCount = users.size();
            int furnitureCount = furniture.size();
            int categoryCount = categories.size();
            
            // 计算库存总价值
            BigDecimal totalValue = furniture.stream()
                .map(f -> f.getPrice().multiply(BigDecimal.valueOf(f.getStock())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            // 计算平均价格
            BigDecimal averagePrice = furnitureCount > 0 ? 
                furniture.stream()
                    .map(Furniture::getPrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(furnitureCount), 2, BigDecimal.ROUND_HALF_UP) :
                BigDecimal.ZERO;
            
            // 计算库存不足的家具数量（库存小于等于5）
            long lowStockCount = furniture.stream()
                .filter(f -> f.getStock() <= 5)
                .count();
            
            Map<String, Object> overview = new HashMap<>();
            overview.put("userCount", userCount);
            overview.put("furnitureCount", furnitureCount);
            overview.put("categoryCount", categoryCount);
            overview.put("totalValue", totalValue);
            overview.put("averagePrice", averagePrice);
            overview.put("lowStockCount", lowStockCount);
            
            logger.info("统计概览数据计算完成: 用户{}个, 家具{}个, 分类{}个, 总价值{}", 
                userCount, furnitureCount, categoryCount, totalValue);
            
            return overview;
        } catch (Exception e) {
            logger.error("获取统计概览失败", e);
            throw new RuntimeException("获取统计概览失败", e);
        }
    }

    /**
     * 获取家具统计信息
     * 
     * @return 家具统计数据
     */
    @Override
    public Map<String, Object> getFurnitureStatistics() {
        logger.debug("获取家具统计信息");
        
        try {
            List<Furniture> furniture = furnitureMapper.selectAll();
            List<Category> categories = categoryMapper.selectAll();
            
            // 按分类统计家具数量
            Map<Long, Long> furnitureByCategory = furniture.stream()
                .collect(Collectors.groupingBy(
                    Furniture::getCategoryId,
                    Collectors.counting()
                ));
            
            // 构建分类统计结果
            Map<String, Object> categoryStats = new HashMap<>();
            for (Category category : categories) {
                Long count = furnitureByCategory.getOrDefault(category.getId(), 0L);
                categoryStats.put(category.getName(), count);
            }
            
            // 价格分布
            Map<String, Long> priceDistribution = furniture.stream()
                .collect(Collectors.groupingBy(
                    f -> {
                        BigDecimal price = f.getPrice();
                        if (price.compareTo(BigDecimal.valueOf(1000)) < 0) {
                            return "1000以下";
                        } else if (price.compareTo(BigDecimal.valueOf(5000)) < 0) {
                            return "1000-5000";
                        } else if (price.compareTo(BigDecimal.valueOf(10000)) < 0) {
                            return "5000-10000";
                        } else {
                            return "10000以上";
                        }
                    },
                    Collectors.counting()
                ));
            
            Map<String, Object> statistics = new HashMap<>();
            statistics.put("categoryStats", categoryStats);
            statistics.put("priceDistribution", priceDistribution);
            statistics.put("totalFurniture", furniture.size());
            
            logger.info("家具统计信息计算完成");
            return statistics;
        } catch (Exception e) {
            logger.error("获取家具统计信息失败", e);
            throw new RuntimeException("获取家具统计信息失败", e);
        }
    }

    /**
     * 获取库存统计信息
     * 
     * @return 库存统计数据
     */
    @Override
    public Map<String, Object> getInventoryStatistics() {
        logger.debug("获取库存统计信息");
        
        try {
            List<Furniture> furniture = furnitureMapper.selectAll();
            
            // 库存不足的家具（库存小于等于5）
            List<Furniture> lowStockFurniture = furniture.stream()
                .filter(f -> f.getStock() <= 5)
                .collect(Collectors.toList());
            
            // 缺货的家具（库存为0）
            List<Furniture> outOfStockFurniture = furniture.stream()
                .filter(f -> f.getStock() == 0)
                .collect(Collectors.toList());
            
            // 计算库存总价值
            BigDecimal totalValue = furniture.stream()
                .map(f -> f.getPrice().multiply(BigDecimal.valueOf(f.getStock())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            // 计算总库存数量
            int totalStock = furniture.stream()
                .mapToInt(Furniture::getStock)
                .sum();
            
            Map<String, Object> statistics = new HashMap<>();
            statistics.put("lowStockCount", lowStockFurniture.size());
            statistics.put("outOfStockCount", outOfStockFurniture.size());
            statistics.put("totalValue", totalValue);
            statistics.put("totalStock", totalStock);
            statistics.put("lowStockFurniture", lowStockFurniture);
            statistics.put("outOfStockFurniture", outOfStockFurniture);
            
            logger.info("库存统计信息计算完成: 库存不足{}个, 缺货{}个, 总价值{}", 
                lowStockFurniture.size(), outOfStockFurniture.size(), totalValue);
            
            return statistics;
        } catch (Exception e) {
            logger.error("获取库存统计信息失败", e);
            throw new RuntimeException("获取库存统计信息失败", e);
        }
    }
}
